home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / os2tools / bnklysrc / nodeproc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  35.1 KB  |  946 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software <no-Inc>                   */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          No-Cost<no-tm> Software.                       */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  Copyright (C) 1987, 1988, 1989 by Robert Hartman and Vincent Perriello  */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*               This module was written by Vince Perriello                 */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*                 BinkleyTerm Nodelist processing module                   */
  17. /*                                                                          */
  18. /*                                                                          */
  19. /*    For complete  details  of the licensing restrictions, please refer    */
  20. /*    to the License  agreement,  which  is published in its entirety in    */
  21. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.210.    */
  22. /*                                                                          */
  23. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  24. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  25. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  26. /*    NOT HAVE THESE FILES,  YOU SHOULD  IMMEDIATELY CONTACT THE AUTHORS    */
  27. /*    AT THE  ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO    */
  28. /*    USE   THIS  FILE  WITHOUT  HAVING   ACCEPTED  THE  TERMS  OF   THE    */
  29. /*    BINKLEYTERM  LICENSING AGREEMENT,  OR SUCH OTHER  AGREEMENT AS YOU    */
  30. /*    ARE ABLE TO REACH WITH THE AUTHORS.                                   */
  31. /*                                                                          */
  32. /*                                                                          */
  33. /*    The Authors can be reached at the following addresses:                */
  34. /*                                                                          */
  35. /*    Robert C. Hartman                      Vincent E. Perriello           */
  36. /*    Spark Software                         VEP Software                   */
  37. /*    427-3 Amherst Street                   111 Carroll Street             */
  38. /*    CS2032, Suite 232                      Naugatuck, CT 06770            */
  39. /*    Nashua, NH 03061                                                      */
  40. /*                                                                          */
  41. /*    FidoNet 1:132/101                      FidoNet 1:141/491              */
  42. /*    Data    (603) 888-8179                 Data    (203) 729-7569         */
  43. /*                                                                          */
  44. /*    Please feel free to contact us at any time to share your comments     */
  45. /*    about our software and/or licensing policies.                         */
  46. /*                                                                          */
  47. /*--------------------------------------------------------------------------*/
  48.  
  49. #include <sys\types.h>
  50. #include <sys\stat.h>
  51. #include <stdio.h>
  52. #include <fcntl.h>
  53. #include <signal.h>
  54. #include <ctype.h>
  55. #include <conio.h>
  56. #include <dos.h>
  57. #include <io.h>
  58. #include <string.h>
  59.  
  60. #ifdef __TURBOC__
  61. #include <alloc.h>
  62. #define _fmalloc(n) farmalloc (n)
  63. #else
  64. #include <malloc.h>
  65. #endif
  66.  
  67. #include "com.h"
  68. #include "xfer.h"
  69. #include "zmodem.h"
  70. #include "keybd.h"
  71. #include "sbuf.h"
  72. #include "sched.h"
  73. #include "externs.h"
  74. #include "prototyp.h"
  75.  
  76. #ifdef OS_2  /*PLF Fri  05-05-1989  08:50:14 */
  77. #define INCL_DOS
  78. #include <os2.h>
  79. #define _dos_read(fh, buf, size, sizep) DosRead(fh, buf, size, (PUSHORT)sizep)
  80. #endif
  81.  
  82. static char far *get_size (unsigned int);
  83. static int get_new_info (unsigned);
  84. static int get_old_info (unsigned);
  85. static int get_TBBS_info (unsigned, int, int);
  86. static int Quick_Next_Zone (void);
  87. static int opus_next_zone (void);
  88.  
  89. static unsigned int idx_size = 0;                /* number of entries in it   */
  90. static unsigned int zone_offset = 0;
  91. static int last_zone = -1;
  92. static int extra_bytes = 0;
  93.  
  94. static char far *get_size (n)
  95. unsigned int n;
  96. {
  97.    /* If we get this far, then we have to use a straight far pointer */
  98.    return (_fmalloc (n));
  99. }
  100.  
  101. /*---------------------------------------------------------------------------*/
  102. /* NODEPROC                                                                  */
  103. /* Find nodelist entry and set baud to nodelist baud for dialing out         */
  104. /*---------------------------------------------------------------------------*/
  105.  
  106. int nodeproc (nodeaddr)
  107. char *nodeaddr;
  108. {
  109.    int opuszone, opusnet, opusnode;              /* zone, net and node */
  110.    char *c, *skip_blanks ();
  111.  
  112.    c = skip_blanks (nodeaddr);                   /* get rid of the blanks     */
  113.    if (sscanf (c, "%d:%d/%d", &opuszone, &opusnet, &opusnode) != 3)
  114.       {
  115.       opuszone = alias[0].Zone;
  116.       if (sscanf (c, "%d/%d", &opusnet, &opusnode) != 2)
  117.          {
  118. /*
  119.          opusnet = alias[0].Net;
  120.          if (sscanf (c, "%d", &opusnode) != 1)
  121.             {
  122.             status_line ("!Can't convert Net/Node address");
  123.             return (0);
  124.             }
  125. */
  126. status_line ("!Can't convert Net/Node address");    /*PLF Mon  05-08-1989  07:26:29 */
  127. return (0);
  128.          }
  129.       }
  130.    if (!nodefind (opuszone, opusnet, opusnode, 1)){ /* if we can't find the node */
  131.       status_line ("!Can't convert Net/Node address");    /*PLF Mon  05-08-1989  07:26:29 */
  132.       return (0);                                /* go away now               */
  133.     }
  134.    if (opuszone != alias[0].Zone)
  135.       {
  136.       status_line ("*Processing node %d:%d/%d -- %s", opuszone, opusnet, opusnode, newnodedes.SystemName);
  137.       }
  138.    else
  139.       {
  140.       status_line ("*Processing node %d/%d -- %s", opusnet, opusnode, newnodedes.SystemName);
  141.       }
  142.    if (!CARRIER)                                 /* if no carrier yet,        */
  143.       {
  144.       if (autobaud)
  145.          set_baud (max_baud, 1);             /* Set to our highest baud
  146.                                                   * rate */
  147.       else set_baud ((300 * newnodedes.BaudRate), 1);       /* set baud to nodelist
  148.                                                                  * baud */
  149.       }
  150.    return (1);                                   /* return success to caller  */
  151. }
  152.  
  153. /*---------------------------------------------------------------------------*/
  154. /* NODEFIND                                                                  */
  155. /* Find nodelist entry for use by other routines (password, nodeproc)        */
  156. /* If found, result will be in "newnodedes".                                 */
  157. /*---------------------------------------------------------------------------*/
  158.  
  159. int nodefind (binkzone, binknet, binknode, prtflag)
  160. int binkzone, binknet, binknode;                 /* zone, net and node */
  161. int prtflag;
  162. {
  163.    int i, j;
  164.    int have_boss_data = 0;
  165.    int need_boss_data = 0;
  166.  
  167.    newnodedes.NetNumber = newnodedes.NodeNumber = found_zone = 0;
  168.  
  169.    CurrentOKFile = DEFAULT.rq_OKFile;    /* Set the default f.req paths */
  170.    CurrentFILES = DEFAULT.rq_FILES;
  171.    CurrentAbout = DEFAULT.rq_About;
  172.    CurrentReqTemplate = DEFAULT.rq_Template;
  173.    CurrentNetFiles = DEFAULT.sc_Inbound;
  174.    CurrentReqLim = DEFAULT.rq_Limit;
  175.  
  176.    if ((binknet == boss_net) && (binknode == boss_node) &&
  177.        (binkzone == alias[0].Zone))
  178.       {
  179.       ++need_boss_data;
  180.     /*PLF Mon  05-08-1989  06:07:21 */
  181.     /* BugAmundo. Referencing NULL pointers causes a GP Fault in os/2
  182.      *if (strlen (BOSSphone) > 2)
  183.      *   ++have_boss_data;
  184.      *if (strlen (BOSSpwd) > 2)
  185.      *   ++have_boss_data;
  186.      *}
  187.      */
  188.       if (BOSSphone && strlen (BOSSphone) > 2)
  189.          ++have_boss_data;
  190.       if (BOSSpwd && strlen (BOSSpwd) > 2)
  191.          ++have_boss_data;
  192.       }
  193.  
  194.    if (!binkzone)
  195.       {
  196.       i = (*nodefunc) (alias[0].Zone, binknet, binknode, have_boss_data);
  197.       if (i) goto lookup_done;
  198.       }
  199.    i = (*nodefunc) (binkzone, binknet, binknode, have_boss_data);
  200.  
  201. lookup_done:
  202.  
  203.    assumed = 0;                              /* Default to zone of first */
  204.    for (j = 0; j < num_addrs; j++)
  205.       {
  206.       if (alias[j].Zone == found_zone)
  207.          {
  208.          assumed = j;
  209.          break;
  210.          }
  211.       }
  212.       
  213.    if (!i && (have_boss_data != 2))
  214.       {
  215.       if (prtflag)
  216.          status_line ("!Couldn't find Zone/Net/Node: %d:%d/%d",
  217.                       binkzone, binknet, binknode);
  218.  
  219.       if (curmudgeon && CARRIER && binknet != -1 && binknode != -1)
  220.          {
  221.          status_line ("!Disconnecting nuisance caller");
  222.          DTR_OFF ();                            /* Hang up right now      */
  223.          timer (2);                             /* Wait two secs          */
  224.          DTR_ON ();                             /* OK, turn modem back on */
  225.          }
  226.  
  227.       }
  228.  
  229.    if (binkzone == -1)
  230.       return i;
  231.  
  232.    /* If we found the entry, then we promote the file request
  233.     * to the "KNOWN" class. If the password field is non-zero,
  234.     * then promote to "PROT". It's OK to do that since the higher
  235.     * level code will hang up before f.req's if the password does
  236.     * not match.
  237.     *
  238.     */
  239.  
  240.    if (i)
  241.       {
  242.       if (newnodedes.Password[0])
  243.          {
  244.          CurrentOKFile = PROT.rq_OKFile;
  245.          CurrentFILES = PROT.rq_FILES;
  246.          CurrentAbout = PROT.rq_About;
  247.          CurrentReqTemplate = PROT.rq_Template;
  248.          CurrentNetFiles = PROT.sc_Inbound;
  249.          CurrentReqLim = PROT.rq_Limit;
  250.          }
  251.       else
  252.          {
  253.          CurrentOKFile = KNOWN.rq_OKFile;
  254.          CurrentFILES = KNOWN.rq_FILES;
  255.          CurrentAbout = KNOWN.rq_About;
  256.          CurrentReqTemplate = KNOWN.rq_Template;
  257.          CurrentNetFiles = KNOWN.sc_Inbound;
  258.          CurrentReqLim = KNOWN.rq_Limit;
  259.          }
  260.       }
  261.  
  262.    if (!need_boss_data)
  263.       return (i);
  264.  
  265. /*
  266.  *    We can get here one of two ways:
  267.  *
  268.  *    1) No nodelist data was found and this is the BOSS.
  269.  *
  270.  *    2) Nodelist lookup occurred, but this is the BOSS.
  271.  *
  272.  *    For case (1), have_boss_data MUST be 2 (meaning we have
  273.  *    both a phone number and a password entry). If that is the
  274.  *    case, fill in newnodedes with mostly zeroes, plugging in
  275.  *    the BOSS net, node, phone number and password.
  276.  *
  277.  *    For case (2), just see if there is any substitution for
  278.  *    BOSSphone and/or BOSSpwd, then exit.
  279.  *
  280.  */
  281.  
  282.    if (BOSSphone && strlen (BOSSphone) > 2) /*PLF Mon  05-08-1989  06:09:41 */
  283.       {
  284.       strncpy (newnodedes.PhoneNumber, BOSSphone, 40);
  285.       newnodedes.PhoneNumber[39] = '\0';
  286.       }
  287.  
  288.    if (BOSSpwd && strlen (BOSSpwd) > 2) /*PLF Mon  05-08-1989  06:09:51 */
  289.       {
  290.       strncpy (newnodedes.Password, BOSSpwd, 8);
  291.       newnodedes.Password[7] = '\0';
  292.       }
  293.  
  294.    if (i)
  295.       return (1);
  296.  
  297.    /* No BOSS in the nodelist */
  298.    if (have_boss_data != 2){
  299.       status_line ("!No BOSS in the nodelist");    /*PLF Mon  05-08-1989  07:26:29 */
  300.       return (0);
  301.     }
  302.  
  303.    newnodedes.NodeNumber = binknode;             /* Node Number */
  304.    newnodedes.NetNumber = binknet;               /* Net Number  */
  305.    newnodedes.Cost = newnodedes.RealCost = 0;    /* Assume boss is free */
  306.    strcpy (newnodedes.SystemName, "Binkley's Boss");    /* System Name defaults */
  307.    strcpy (newnodedes.MiscInfo, "Somewhere out There"); /* As does City */
  308.    newnodedes.HubNode = 0;                       /* Don't know who is HUB */
  309.    newnodedes.BaudRate = (char) (max_baud / 300);/* Assume boss speed = ours */
  310.    newnodedes.ModemType = 0;                     /* Or modem type */
  311.    newnodedes.NodeFlags = B_CM;                  /* Assume boss is CM */
  312.    newnodedes.NodeFiller = 0;                    /* Zero out filler */
  313.    return (1);
  314. }
  315.  
  316. static int Quick_Next_Zone ()
  317. {
  318.    register struct QuickNodeIdxRecord far *nodeidx;     /* index file         */
  319.    register unsigned int i;
  320.  
  321.    if (no_zones)
  322.       return (-1);
  323.  
  324.    nodeidx = (struct QuickNodeIdxRecord far *) (node_index + (zone_offset *
  325.               sizeof (struct QuickNodeIdxRecord)));
  326.    for (i = zone_offset; i < idx_size; ++nodeidx, i++)
  327.       {
  328.       if (nodeidx->QI_Zone != last_zone)
  329.          {
  330.          last_zone = nodeidx->QI_Zone;
  331.          zone_offset = i + 1;
  332.          return (last_zone);
  333.          }
  334.       }
  335.  
  336.    last_zone = -1;
  337.    zone_offset = 0;
  338.    return (-1);
  339. }
  340.  
  341.  
  342. int QuickLookup (Quickzone, Quicknet, Quicknode, have_boss_data)
  343. int Quickzone, Quicknet, Quicknode;              /* zone, net and node */
  344. int have_boss_data;                              /* BOSS data flag     */
  345. {
  346.    register struct QuickNodeIdxRecord far *nodeidx;     /* index file         */
  347.    struct QuickNodeListRecord nodedes;           /* desc. of node      */
  348.  
  349.    int foundnet = 0;                             /* 'found the net' flag      */
  350.    int found = 0;                                /* 'found the node' flag     */
  351.    int idxrec = 0;                               /* record in QNL_IDX.BBS     */
  352.    long nodeoff = 0L;                            /* offset into QNL_DAT.BBS   */
  353.    char temp[80];                                /* where we build filenames  */
  354.    unsigned int i;
  355.    int stream;
  356.    FILE *stream1;
  357.    int got;
  358.    struct stat f;
  359.  
  360.    newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  361.  
  362.    if (node_index == NULL)
  363.       {
  364.       temp[0] = '\0';                            /* "null-terminated string"  */
  365.       strcpy (temp, net_info);                   /* take nodelist path        */
  366.       strcat (temp, "QNL_IDX.BBS");              /* add in the file name      */
  367.       if ((stream = open(temp, O_RDONLY)) == -1)
  368.          {
  369.          if (have_boss_data != 2)
  370.             status_line ("!Unable to open %s", temp);
  371.          return (0);                             /* no file, no work to do    */
  372.          }
  373.       fstat (stream, &f);                        /* get file statistics       */
  374.       i = (unsigned int) f.st_size;              /* size of index file,       */
  375.       idx_size = i / sizeof (*nodeidx);          /* number of index entries   */
  376.       node_index = get_size (i);
  377.       if (node_index == NULL)
  378.          {
  379.          status_line ("!Unable to allocate memory for Nodelist Index");
  380.          close (stream);
  381.          return (0);
  382.          }
  383.       if (_dos_read (stream, node_index, i, &got) != 0)
  384.          {
  385.          status_line ("!Failed to read nodelist index into memory");
  386.          close (stream);
  387.          return (0);
  388.          }
  389.       close (stream);
  390.       }
  391.    nodeidx = (struct QuickNodeIdxRecord far *) node_index;
  392.  
  393.  
  394.    if (Quickzone < 0)
  395.       {
  396.       return (Quick_Next_Zone ());
  397.       }
  398.    else if (no_zones)
  399.       Quickzone = 0;
  400.  
  401.    for (i = 1; i <= idx_size; idxrec++, nodeidx++, i++)
  402.       {
  403.       if (((Quickzone == nodeidx->QI_Zone) || (Quickzone == 0))
  404.           && (Quicknet == nodeidx->QI_Net))
  405.          {
  406.          foundnet = 1;                           /* say we found the net      */
  407.          if (((Quicknode == 0) && (nodeidx->QI_Node <= 0))
  408.              || (nodeidx->QI_Node == Quicknode)) /* see if we found the node  */
  409.             {
  410.             found = 1;                           /* say we found it           */
  411.             break;                               /* get out                   */
  412.             }
  413.          }
  414.       else if (foundnet)                         /* already past the net?     */
  415.          break;                                  /* Yes, we failed...         */
  416.       }
  417.  
  418.    if (!found)
  419.       {
  420.       return (0);
  421.       }
  422.  
  423.  
  424.    nodeoff = (long) idxrec *(long) sizeof (nodedes);    /* actual file offset   */
  425.  
  426.    strcpy (temp, net_info);                      /* take nodelist path        */
  427.    strcat (temp, "QNL_DAT.BBS");                 /* add in the file name      */
  428.    if ((stream1 = fopen (temp, "rb")) == NULL)   /* OK, let's open the file   */
  429.       {
  430.       status_line ("!Unable to open %s", temp);
  431.       return (0);
  432.       }
  433.  
  434.    if (fseek (stream1, nodeoff, SEEK_SET))       /* try to point at record    */
  435.       {
  436.       status_line ("!Unable to position to node record in %s", temp);
  437.       fclose (stream1);
  438.       return (0);
  439.       }
  440.  
  441.    if (!fread (&nodedes, sizeof (nodedes), 1, stream1))
  442.       {
  443.       status_line ("!Not able to read node record from %s", temp);
  444.       fclose (stream1);
  445.       return (0);
  446.       }
  447.    fclose (stream1);
  448.  
  449.    /*
  450.     * Copy data from nodedes into newnodedes. 
  451.     */
  452.  
  453.    newnodedes.NodeNumber = nodedes.QL_Node;      /* Node Number  */
  454.    newnodedes.NetNumber = nodedes.QL_Net;        /* Net Number   */
  455.    newnodedes.Cost = nodedes.QL_Cost;            /* Cost         */
  456.  
  457.    i = min (nodedes.QL_Name[0], 19);
  458.    strncpy (&newnodedes.SystemName[0], &nodedes.QL_Name[1], i);
  459.    newnodedes.SystemName[i] = '\0';              /* System Name  */
  460.  
  461.    i = min (nodedes.QL_Phone[0], 39);
  462.    strncpy (&newnodedes.PhoneNumber[0], &nodedes.QL_Phone[1], i);
  463.    newnodedes.PhoneNumber[i] = '\0';             /* Phone Number */
  464.  
  465.    i = min (nodedes.QL_City[0], 29);
  466.    strncpy (&newnodedes.MiscInfo[0], &nodedes.QL_City[1], i);
  467.    newnodedes.MiscInfo[i] = '\0';
  468.  
  469.    /* This field is not necessarily null terminated */
  470.    i = min (nodedes.QL_Password[0], 8);
  471.    strncpy (&newnodedes.Password[0], &nodedes.QL_Password[1], i);
  472.    if (i < 8)
  473.       newnodedes.Password[i] = '\0';
  474.  
  475.    /* Adam Hudson now gives us this, so we might as well use it */
  476.    newnodedes.NodeFlags = nodedes.QL_Flags;
  477.  
  478.    /* Since we have the stuff we need! */
  479.    newnodelist = 1;                              /* We have all the
  480.                                                   * information! */
  481.  
  482.    newnodedes.RealCost = nodedes.QL_Cost;        /* Cost               */
  483.    newnodedes.HubNode = 0;                       /* Don't know who is Hub    */
  484.    newnodedes.BaudRate = (char) (nodedes.QL_BaudRate / 300);    /* Baud     */
  485.    newnodedes.ModemType = 0;                     /* Don't know modem type    */
  486.    newnodedes.NodeFiller = 0;                    /* Filler should be zero    */
  487.    found_zone = nodeidx -> QI_Zone;              /* Keep track of found zone */
  488.    return (1);
  489. }
  490.  
  491. static int opus_next_zone ()
  492. {
  493.    register struct _ndi far *nodeidx;            /* index file                */
  494.    register unsigned int i;
  495.  
  496.    if (no_zones)
  497.       return (-1);
  498.  
  499.    if (zone_offset == 0)
  500.       zone_offset = 1;
  501.  
  502.    nodeidx = (struct _ndi far *) (node_index + (zone_offset *
  503.              sizeof (struct _ndi)));
  504.  
  505.    for (i = zone_offset; i < idx_size; ++nodeidx, i++)
  506.       {
  507.       if (nodeidx->node == -2)
  508.          {
  509.          last_zone = nodeidx->net;
  510.          zone_offset = i + 1;
  511.          return (last_zone);
  512.          }
  513.       }
  514.  
  515.    last_zone = -1;
  516.    zone_offset = 0;
  517.    return (-1);
  518. }
  519.  
  520. int opusfind (opuszone, opusnet, opusnode, have_boss_data)
  521. int opuszone, opusnet, opusnode;                 /* zone, net and node */
  522. int have_boss_data;                              /* BOSS data flag     */
  523. {
  524.    register struct _ndi far *nodeidx;            /* index file                */
  525. /* int foundnet = 0;   */                        /* 'found the net' flag      */
  526.    int found = 0;                                /* 'found the node' flag     */
  527.    int nodeoff = 0;                              /* offset into nodelist.sys  */
  528.    char temp[80];                                /* where we build filenames  */
  529.    unsigned int i;
  530.    int stream;
  531.    struct stat f;
  532.    int current_zone = 0;
  533.    int got;
  534.  
  535.    newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  536.  
  537.    if (node_index == NULL)
  538.       {
  539.       temp[0] = '\0';                            /* "null-terminated string"  */
  540.       strcpy (temp, net_info);                   /* take nodelist path        */
  541.       strcat (temp, "NODELIST.IDX");             /* add in the file name      */
  542.       if ((stream = open(temp, O_RDONLY)) == -1)
  543.          {
  544.          i = 0;                                  /* Need this later           */
  545.          if (have_boss_data != 2)
  546.             status_line ("!Unable to open Nodelist.Idx file");
  547.          return (0);                             /* no file, no work to do    */
  548.          }
  549.       fstat (stream, &f);                        /* get file statistics       */
  550.       i = (unsigned int) f.st_size;              /* size of index file,       */
  551.       idx_size = i / sizeof (struct _ndi);       /* number of index entries   */
  552.  
  553.       /*
  554.        * Now take into account that the .DAT file can be bigger than we
  555.        * really expect it to be.  Just take the number of records, and
  556.        * divide into the size of the .DAT file to find the true record size
  557.        */
  558.       if (newnodelist)
  559.          {
  560.          temp[0] = '\0';                            /* "null-terminated string"  */
  561.          strcpy (temp, net_info);                   /* take nodelist path        */
  562.          strcat (temp, "NODELIST.DAT");             /* add in the file name      */
  563.          if (!stat (temp, &f))
  564.             {
  565.             extra_bytes = ((int) (f.st_size / idx_size)) - sizeof (newnodedes);
  566.             }
  567.          }
  568.  
  569.       node_index = get_size (i);
  570.       if (node_index == NULL)
  571.          {
  572.          status_line ("!Unable to allocate memory for Nodelist Index");
  573.          close (stream);
  574.          return (0);
  575.          }
  576.       if (_dos_read (stream, node_index, i, &got) != 0)
  577.          {
  578.          status_line ("!Failed to read nodelist index into memory");
  579.          close (stream);
  580.          return (0);
  581.          }
  582.       close (stream);
  583.       }
  584.  
  585.    nodeidx = (struct _ndi far *) node_index;
  586.  
  587.    /* If using the old nodelist, bypass zone stuff - it isn't there */
  588.    if (opuszone < 0)
  589.       {
  590.       return (opus_next_zone ());
  591.       }
  592.    else if ((!newnodelist) || (alias[0].Zone == 0) || (no_zones))
  593.       {
  594.       opuszone = 0;
  595.       }
  596.  
  597.    for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++)
  598.       {
  599.       if (nodeidx->node == -2)
  600.      current_zone = nodeidx->net;
  601.      
  602.       if (opuszone > 0 && current_zone != opuszone)
  603.             continue;
  604.  
  605.       if (nodeidx->net == opusnet)               /* if a match on net,        */
  606.          {
  607. /*       foundnet = 1;   */                      /* say we found the net      */
  608.          if (((opusnode == 0) && (nodeidx->node <= 0))
  609.              || (nodeidx->node == opusnode))     /* see if we found the node  */
  610.             {
  611.             found = 1;                           /* say we found it           */
  612.             break;                               /* get out                   */
  613.             }
  614.          }
  615.  
  616.       /*
  617.        * This code is good, but many people complained about not being able
  618.        * to add nodes to nets by adding them at the end of the nodelist.  So,
  619.        * I commented this stuff out for now. - Bob
  620.        */
  621. /*      else*/
  622.       /*      if (foundnet)*//* already past the net?     */
  623.       /*         break;*//* Yes, we failed...         */
  624.       }
  625.  
  626.    if (!found)
  627.       return (0);
  628.  
  629.    found_zone = current_zone;                    /* Keep track of found zone */
  630.  
  631.    if (newnodelist)
  632.       i = (get_new_info (nodeoff));
  633.    else i = (get_old_info (nodeoff));
  634.  
  635.    return (i);
  636. }
  637.  
  638.  
  639. static int get_old_info (recno)
  640. unsigned recno;
  641. {
  642.    struct _node nodedes;                         /* desc. of node             */
  643.    long nodeoff;                                 /* Offset into NODELIST.SYS  */
  644.    char temp[80];                                /* where we build filenames  */
  645.    char *c, *ch;
  646.    int i;
  647.    FILE *stream;
  648.  
  649.    nodeoff = (long) recno *(long) sizeof (nodedes);     /* actual file offset        */
  650.  
  651.    strcpy (temp, net_info);                      /* take nodelist path        */
  652.    strcat (temp, "NODELIST.SYS");                /* add in the file name      */
  653.    if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  654.       {
  655.       status_line ("!Unable to open Nodelist.Sys file");
  656.       return (0);
  657.       }
  658.  
  659.    if (fseek (stream, nodeoff, SEEK_SET))        /* try to point at record    */
  660.       {
  661.       status_line ("!Unable to position to node record in Nodelist.Sys");
  662.       fclose (stream);
  663.       return (0);
  664.       }
  665.  
  666.    if (!fread (&nodedes, sizeof (nodedes), 1, stream))
  667.       {
  668.       status_line ("!Not able to read node record from Nodelist.Sys");
  669.       fclose (stream);
  670.       return (0);
  671.       }
  672.    fclose (stream);
  673.  
  674.    /*
  675.     * Copy data from nodedes into newnodedes. 
  676.     */
  677.  
  678.    newnodedes.NodeNumber = nodedes.number;       /* Node Number  */
  679.    newnodedes.NetNumber = nodedes.net;           /* Net Number   */
  680.    newnodedes.Cost = nodedes.cost;               /* Cost         */
  681.  
  682.    strncpy (&newnodedes.SystemName[0], &nodedes.name[0], 20);
  683.    newnodedes.SystemName[19] = '\0';             /* System Name  */
  684.  
  685.    strncpy (&newnodedes.PhoneNumber[0], &nodedes.phone[0], 40);
  686.    newnodedes.PhoneNumber[39] = '\0';            /* Phone Number */
  687.  
  688.    strncpy (&newnodedes.MiscInfo[0], &nodedes.city[0], 30);
  689.    newnodedes.MiscInfo[29] = '\0';
  690.  
  691.    ch = NULL;                                    /* Pointer to password      */
  692.    c = nodedes.city;                             /* Point to start of city   */
  693.    i = 37;                                       /* No password if this = 0  */
  694.    while (i--)                                   /* Enforce that limit       */
  695.       {
  696.       if (*c++ != '\0')                          /* If not at end of city,   */
  697.          continue;                               /* go on to next character  */
  698.       if (*c++ != '!')                           /* End of city, got '!' ??  */
  699.          break;                                  /* No, treat like a failure */
  700.       ch = c;                                    /* Got it, point to it      */
  701.       break;                                     /* Exit with success code   */
  702.       }
  703.    if (ch != NULL)
  704.       {
  705.       strncpy (&newnodedes.Password[0], ch, 8);  /* Copy the password        */
  706.       }
  707.    else newnodedes.Password[0] = '\0';           /* Else set zero length     */
  708.  
  709.    newnodedes.RealCost = nodedes.cost;           /* Cost                     */
  710.    newnodedes.HubNode = 0;                       /* Don't know who is Hub    */
  711.    newnodedes.BaudRate = (char) (nodedes.rate / 300);   /* Baud Rate                */
  712.    newnodedes.ModemType = 0;                     /* Don't know modem type    */
  713.    newnodedes.NodeFlags = 0;                     /* Don't know any flags     */
  714.    newnodedes.NodeFiller = 0;                    /* Filler should be zero    */
  715.    return (1);
  716. }
  717.  
  718. static int get_new_info (recno)
  719. unsigned recno;
  720. {
  721.    long nodeoff;                                 /* Offset into NODELIST.DAT  */
  722.    char temp[80];                                /* where we build filenames  */
  723.    FILE *stream;
  724.  
  725.    /* actual file offset */
  726.    nodeoff = (long) recno * ((long) (sizeof (newnodedes) + extra_bytes));
  727.  
  728.    strcpy (temp, net_info);                      /* take nodelist path        */
  729.    strcat (temp, "NODELIST.DAT");                /* add in the file name      */
  730.    if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  731.       {
  732.       status_line ("!Unable to open Nodelist.Dat file");
  733.       return (0);
  734.       }
  735.  
  736.    if (fseek (stream, nodeoff, SEEK_SET))        /* try to point at record    */
  737.       {
  738.       status_line ("!Unable to position to node record in Nodelist.Dat");
  739.       fclose (stream);
  740.       return (0);
  741.       }
  742.  
  743.    if (!fread (&newnodedes, sizeof (newnodedes), 1, stream))
  744.       {
  745.       status_line ("!Not able to read node record from Nodelist.Dat");
  746.       fclose (stream);
  747.       return (0);
  748.       }
  749.    fclose (stream);
  750.    return (1);
  751. }
  752.  
  753. static int get_TBBS_info (recno, TBBSnet, TBBSnode)
  754. unsigned recno;
  755. int TBBSnet, TBBSnode;
  756. {
  757.    struct nodels nodedes;                        /* desc. of node             */
  758.    struct extrastuff ext;                        /* Extra stuff for Binkley   */
  759.    long nodeoff;                                 /* Offset into NODELIST.DOG  */
  760.    char temp[80];                                /* where we build filenames  */
  761.    FILE *stream;
  762.  
  763.    --recno;                                      /* TBBS list starts at first
  764.                                                   * record - no filler */
  765.  
  766.    nodeoff = (long) recno *(long) sizeof (nodedes);     /* actual file offset        */
  767.  
  768.    strcpy (temp, net_info);                      /* take nodelist path        */
  769.    strcat (temp, "NODELIST.DOG");                /* add in the file name      */
  770.    if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  771.       {
  772.       status_line ("!Unable to open Nodelist.Dog file");
  773.       return (0);
  774.       }
  775.  
  776.    if (fseek (stream, nodeoff, SEEK_SET))        /* try to point at record    */
  777.       {
  778.       status_line ("!Unable to position to node record in Nodelist.Dog");
  779.       fclose (stream);
  780.       return (0);
  781.       }
  782.  
  783.    if (!fread (&nodedes, sizeof (nodedes), 1, stream))
  784.       {
  785.       status_line ("!Not able to read node record from Nodelist.Dog");
  786.       fclose (stream);
  787.       return (0);
  788.       }
  789.    fclose (stream);
  790.  
  791.    /*
  792.     * Copy data from nodedes into newnodedes. 
  793.     */
  794.  
  795.    newnodedes.NodeNumber = TBBSnode;             /* Node Number  */
  796.    newnodedes.NetNumber = TBBSnet;               /* Net Number   */
  797.    newnodedes.Cost = nodedes.nodecost;           /* Cost         */
  798.  
  799.    strncpy (&newnodedes.SystemName[0], &nodedes.nodename[0], 14);
  800.    newnodedes.SystemName[19] = '\0';             /* System Name  */
  801.  
  802.    strncpy (&newnodedes.PhoneNumber[0], &nodedes.nodephone[0], 40);
  803.    newnodedes.PhoneNumber[39] = '\0';            /* Phone Number */
  804.  
  805.    strncpy (&newnodedes.MiscInfo[0], &nodedes.nodecity[0], 30);
  806.    newnodedes.MiscInfo[29] = '\0';
  807.  
  808.    newnodedes.Password[0] = '\0';                /* Else set zero length     */
  809.  
  810.    newnodedes.RealCost = nodedes.nodecost;       /* Cost                     */
  811.    newnodedes.HubNode = nodedes.nodehub;         /* Hub */
  812.    newnodedes.BaudRate = (char) (nodedes.nodebaud / 300);       /* Baud Rate                */
  813.    newnodedes.ModemType = 0;                     /* Don't know modem type    */
  814.    newnodedes.NodeFlags = 0;                     /* Don't know any flags     */
  815.    newnodedes.NodeFiller = 0;                    /* Filler should be zero    */
  816.  
  817.    /* Now get information from secondary file */
  818.    ++recno;
  819.    nodeoff = (long) recno *(long) sizeof (ext);  /* actual file offset        */
  820.  
  821.    strcpy (temp, net_info);                      /* take nodelist path        */
  822.    strcat (temp, "NODELIST.EXT");                /* add in the file name      */
  823.    newnodelist = 0;
  824.    if ((stream = fopen (temp, "rb")) == NULL)    /* OK, let's open the file   */
  825.       {
  826.       return (1);
  827.       }
  828.  
  829.    if (fseek (stream, nodeoff, SEEK_SET))        /* try to point at record    */
  830.       {
  831.       fclose (stream);
  832.       return (1);
  833.       }
  834.  
  835.    if (!fread (&ext, sizeof (ext), 1, stream))
  836.       {
  837.       fclose (stream);
  838.       return (1);
  839.       }
  840.    fclose (stream);
  841.  
  842.    /*
  843.     * Copy data from ext into newnodedes. 
  844.     */
  845.  
  846.    strncpy (newnodedes.Password, ext.password, 8);      /* Password */
  847.  
  848.    newnodedes.NodeFlags = ext.flags1;            /* Nodelist flags */
  849.    newnodelist = 1;                              /* We have all the
  850.                                                   * information! */
  851.    return (1);
  852. }
  853.  
  854. int TBBSLookup (TBBSzone, TBBSnet, TBBSnode, have_boss_data)
  855. int TBBSzone, TBBSnet, TBBSnode;                 /* zone, net and node */
  856. int have_boss_data;                              /* BOSS data flag     */
  857. {
  858.    register struct _ndi far *nodeidx;            /* index file                */
  859. /* int foundnet = 0; */                          /* 'found the net' flag      */
  860.    int found = 0;                                /* 'found the node' flag     */
  861.    int nodeoff = 0;                              /* offset into nodelist.sys  */
  862.    char temp[80];                                /* where we build filenames  */
  863.    unsigned int i;
  864.    int stream;
  865.    struct stat f;
  866.    int current_zone = 0;
  867.    int got;
  868.  
  869.    newnodedes.NetNumber = newnodedes.NodeNumber = 0;
  870.  
  871.    if (node_index == NULL)
  872.       {
  873.       temp[0] = '\0';                            /* "null-terminated string"  */
  874.       strcpy (temp, net_info);                   /* take nodelist path        */
  875.       strcat (temp, "NODELIST.IDX");             /* add in the file name      */
  876.       if ((stream = open(temp, O_RDONLY)) == -1)
  877.          {
  878.          i = 0;                                  /* Need this later           */
  879.          if (have_boss_data != 2)
  880.             status_line ("!Unable to open Nodelist.Idx file");
  881.          return (0);                             /* no file, no work to do    */
  882.          }
  883.       fstat (stream, &f);                        /* get file statistics       */
  884.       i = (unsigned int) f.st_size;              /* size of index file,       */
  885.       idx_size = i / sizeof (struct _ndi);       /* number of index entries   */
  886.       node_index = get_size (i);
  887.       if (node_index == NULL)
  888.          {
  889.          status_line ("!Unable to allocate memory for Nodelist Index");
  890.          close (stream);
  891.          return (0);
  892.          }
  893.       if (_dos_read (stream, node_index, i, &got) != 0)
  894.          {
  895.          status_line ("!Failed to read nodelist index into memory");
  896.          close (stream);
  897.          return (0);
  898.          }
  899.       close (stream);
  900.       }
  901.    nodeidx = (struct _ndi far *) node_index;
  902.  
  903.    if (TBBSzone < 0)
  904.       {
  905.       return (opus_next_zone ());
  906.       }
  907.  
  908.    for (i = 1; i <= idx_size; nodeoff++, nodeidx++, i++)
  909.       {
  910.       if (nodeidx->node == -2)
  911.      current_zone = nodeidx->net;
  912.      
  913.       if (TBBSzone > 0 && current_zone != TBBSzone)
  914.             continue;
  915.  
  916.       if (nodeidx->net == TBBSnet)               /* if a match on net,        */
  917.          {
  918. /*       foundnet = 1;  */                       /* say we found the net      */
  919.          if (((TBBSnode == 0) && (nodeidx->node <= 0))
  920.              || (nodeidx->node == TBBSnode))     /* see if we found the node  */
  921.             {
  922.             found = 1;                           /* say we found it           */
  923.             break;                               /* get out                   */
  924.             }
  925.          }
  926.  
  927.       /*
  928.        * This code is good, but many people complained about not being able
  929.        * to add nodes to nets by adding them at the end of the nodelist.  So,
  930.        * I commented this stuff out for now. - Bob 
  931.        */
  932. /*      else*/
  933.       /*      if (foundnet)*//* already past the net?     */
  934.       /*         break;*//* Yes, we failed...         */
  935.       }
  936.  
  937.    if (!found)
  938.       return (0);
  939.  
  940.    found_zone = current_zone;                    /* Keep track of found zone */
  941.  
  942.    i = get_TBBS_info (nodeoff, TBBSnet, TBBSnode);
  943.  
  944.    return (i);
  945. }
  946.